﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using EnvDTE;
using EnvDTE80;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.Common;
using Microsoft.VisualStudio.TextTemplating;
using CoNatural.Data.VisualStudio.AddIn.Tools;

namespace CoNatural.Data.VisualStudio.AddIn.Helpers {
	internal class TemplateBuilder {
		private ProjectItems rootCollection;
		private string rootPath;
		private string rootNamespace;
		private Microsoft.VisualStudio.TextTemplating.Engine engine;

		public TemplateBuilder(ProjectItems rootCollection, string rootPath, string rootNamespace) {
			this.rootCollection = rootCollection;
			this.rootPath = rootPath;
			this.rootNamespace = rootNamespace;
			engine = new Microsoft.VisualStudio.TextTemplating.Engine();
		}

		private string LoadTemplate(string path) {
			if (File.Exists(path))
				return File.ReadAllText(path);
			return null;
		}

 		private void CreateFile(string csFilePath, Table sqlTable, string commandNamespace, string commandName, string template) {
			using (var host = new TemplateHost(sqlTable, commandNamespace, commandName)) {
				string csFileText = engine.ProcessTemplate(template, host);
				if (host.Errors.HasErrors) {
					var sb = new StringBuilder();
					foreach (var error in host.Errors)
						sb.AppendLine(error.ToString());
					File.WriteAllText(csFilePath, sb.ToString());
				}
				else {
					File.WriteAllText(csFilePath, csFileText);
				}
			}
		}

		internal void Create(Model.DbObject sp, Table sqlTable, string templatePath) {
			string template = LoadTemplate(templatePath);
			if (template != null) {
				string commandName;
				string collectionPath;
				string commandNamespace;
				ProjectItems collection = ProjectItemHelper.LocateCollection(rootCollection, rootPath, rootNamespace, sp.CommandName, out commandName, out commandNamespace, out collectionPath);
				string csFilePath = Path.Combine(collectionPath, string.Concat(commandName, Path.GetFileNameWithoutExtension(templatePath), ".cs"));
				CreateFile(csFilePath, sqlTable, commandNamespace, commandName, template);
				collection.AddFromFile(csFilePath);
			}
		}

		private void CreateFile(string csFilePath, StoredProcedure sqlStoredProcedure, string commandNamespace, string commandName, string template) {
			using (var host = new TemplateHost(sqlStoredProcedure, commandNamespace, commandName)) {
				string csFileText = engine.ProcessTemplate(template, host);
				if (host.Errors.HasErrors) {
					var sb = new StringBuilder();
					foreach (var error in host.Errors)
						sb.AppendLine(error.ToString());
					File.WriteAllText(csFilePath, sb.ToString());
				}
				else {
					File.WriteAllText(csFilePath, csFileText);
				}
			}
		}

		internal void Create(Model.DbObject sp, StoredProcedure sqlStoredProcedure, string templatePath) {
			string template = LoadTemplate(templatePath);
			if (template != null) {
				string commandName;
				string collectionPath;
				string commandNamespace;
				ProjectItems collection = ProjectItemHelper.LocateCollection(rootCollection, rootPath, rootNamespace, sp.CommandName, out commandName, out commandNamespace, out collectionPath);
				string csFilePath = Path.Combine(collectionPath, string.Concat(commandName, Path.GetFileNameWithoutExtension(templatePath), ".cs"));
				CreateFile(csFilePath, sqlStoredProcedure, commandNamespace, commandName, template);
				collection.AddFromFile(csFilePath);
			}
		}
	}
}
